/*
 * menu.h
 *
 *  Created on: Feb 3, 2013
 *      Author: justin
 */

#include "project.h"
#ifndef MENU_H
#define MENU_H

/*
 MICRO-MENU

 (C) Dean Camera, 2007
 www.fourwalledcubicle.com
 dean_camera@fourwalledcubicle.com

 Royalty-free for all uses.
 */

// Typedefs:
typedef void (*FuncPtr)(void);
typedef void (*WriteFuncPtr)(const char*);

typedef struct
	 {
		void *Next;
		void *Previous;
		void *Parent;
		void *Sibling;
		FuncPtr SelectFunc;
		FuncPtr EnterFunc;
		const char Text[];
	} Menu_Item ;



// Externs:
	extern WriteFuncPtr* WriteFunc;
	extern Menu_Item Null_Menu;
	extern Menu_Item* CurrMenuItem;

// Defines and Macros:
#define NULL_ENTRY Null_Menu
#define NULL_FUNC  (void*)0
#define NULL_TEXT  0x00

#define PREVIOUS   *((Menu_Item*)(CurrMenuItem->Previous))
#define NEXT       *((Menu_Item*)(CurrMenuItem->Next))
#define PARENT     *((Menu_Item*)(CurrMenuItem->Parent))
#define SIBLING    *((Menu_Item*)(CurrMenuItem->Sibling))
#define ENTERFUNC  *((FuncPtr*)(CurrMenuItem->EnterFunc))
#define SELECTFUNC *((FuncPtr*)(CurrMenuItem->SelectFunc))

#define MAKE_MENU(Name, Next, Previous, Parent, Sibling, SelectFunc, EnterFunc, Text) \
    extern Menu_Item Next;     \
	extern Menu_Item Previous; \
	extern Menu_Item Parent;   \
	extern Menu_Item Sibling;  \
	Menu_Item Name = {(void*)&Next, (void*)&Previous, (void*)&Parent, (void*)&Sibling, (FuncPtr)SelectFunc, (FuncPtr)EnterFunc, { Text }}

#define SET_MENU_WRITE_FUNC(x) \
	WriteFunc = (WriteFuncPtr*)&x;

#define SET_MENU(x) \
	MenuChange((Menu_Item*)&x);

#define GO_MENU_FUNC(x)  \
	MenuFunc((FuncPtr*)&x)

#define EXTERN_MENU(Name) \
    extern Menu_Item Name;

// Prototypes:
	void MenuChange(Menu_Item* NewMenu);
	void MenuFunc(FuncPtr* Function);

#endif /* MENU_H_ */
